home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 163_02 / _format.c next >
Text File  |  1988-01-30  |  5KB  |  159 lines

  1. /*
  2. ** _format(format, argc, argv, call, parm)
  3. **        formatter for printf, fprintf, and sprintf
  4. **        operates as described by Kernighan & Ritchie
  5. **        only d, o, x, c, s, and u specs are supported.
  6. **
  7. ** format -- pointer to a standard printf format string
  8. ** argc   -- number of arguments in argument list
  9. ** argv   -- pointer to argument list (last argument first)
  10. ** call   -- address of function to call (eg, fputc)
  11. ** parm   -- second argument to call (eg, stdout);
  12. */
  13.  
  14. #include <errno.h>
  15. extern int errno, abort(), isdigit();
  16.  
  17. _format(format, argc, argv, call, parm)
  18.     char *format; int argc, *argv, call, parm; {
  19.   int i, width, prec, len;
  20.   char c, left, str[7], *sptr, pad;
  21.   argv += (argc - 1); /* address "first" argument */
  22.   while(c=*format++) {
  23.     if(c!='%') {
  24.       if(call(c, parm) == -1) abort(errno);
  25.       continue;
  26.       }
  27.     if(*format=='%') {
  28.       if(call(*format++, parm) == -1) abort(errno);
  29.       continue;
  30.       }
  31.     if(left=(*format=='-')) ++format;
  32.     if(*format=='0') {pad='0'; ++format;} else pad=' ';
  33.     if(*format == '*') {
  34.       width = *argv--;
  35.       if(!argc--) abort(E2BIG); /* argument list error */
  36.       format++;
  37.       }
  38.     else {
  39.       width = 0;
  40.       if(isdigit(*format)) while(isdigit(c = *format)) {
  41.         width = (width * 10) + (c - '0');
  42.         format++;
  43.         }
  44.       }
  45.     prec = 0;
  46.     if(*format=='.') {
  47.       format++;
  48.       if(*format == '*') {
  49.         prec = *argv--;
  50.         if(!argc--) abort(E2BIG); /* argument list error */
  51.         format++;
  52.         }
  53.       else {
  54.         if(isdigit(*format)) while(isdigit(c = *format)) {
  55.           prec = (prec * 10) + (c - '0');
  56.           format++;
  57.           }
  58.         }
  59.       }
  60.     c=*format++;
  61.     i=*(argv--);
  62.     if(!argc--) abort(E2BIG); /* argument list error */
  63.     sptr=str;
  64.     if(c=='d') itod(i, str);
  65.     else if(c=='u') itou(i, str);
  66.     else if(c=='o') itoo(i, str);
  67.     else if(c=='x') itox(i, str);
  68.     else if(c=='c') {str[0]=i; str[1]=0;}
  69.     else if(c=='s') sptr=i;
  70.     else continue;
  71.     if(c != 's' && c != 'c') while(*sptr==' ') ++sptr;
  72.     len = -1; while(sptr[++len]); /* get length */
  73.     if((c == 's') & (len > prec) & (prec > 0)) len = prec;
  74.     if(!left) while(((width--) - len) > 0)
  75.       if(call(pad, parm) == -1) abort(errno);
  76.     while(len) {
  77.       if(call(*sptr++, parm) == -1) abort(errno);
  78.       --len;
  79.       --width;
  80.       }
  81.     while(((width--) - len) > 0)
  82.       if(call(pad, parm) == -1) abort(errno);
  83.     }
  84.   }
  85.  
  86. /*
  87. ** itod -- convert nbr to signed decimal string of width 7
  88. **         (including null) right adjusted, blank filled
  89. */
  90. static itod(nbr, str) int nbr; char str[]; {
  91.   char sgn;
  92.   int count;
  93.   if(nbr<0) {nbr = -nbr; sgn='-';}
  94.   else sgn=' ';
  95.   str = str+6; /* find end of string */
  96.   *str-- = 0; /* store ending null */
  97.   count = 6; /* remaining characters */
  98.   while(1) {
  99.     *str-- = (nbr % 10 + '0');
  100.     count--;
  101.     if(!(nbr /= 10)) break;
  102.     }
  103.   *str-- = sgn;
  104.   while(--count) *str-- = ' ';
  105.   }
  106.  
  107. /*
  108. ** itou -- convert nbr to unsigned decimal string of width 7
  109. **         (including null) right adjusted, blank filled
  110. */
  111. static itou(nbr, str) int nbr; char str[]; {
  112.   int count, lowbit;
  113.   str = str+6; /* find end of string */
  114.   *str-- = 0; /* store ending null */
  115.   count = 6; /* remaining characters */
  116.   while(1) {
  117.     lowbit = nbr & 1;
  118.     nbr = (nbr >> 1) & 32767;  /* divide by 2 */
  119.     *str-- = ((nbr % 5) << 1) + lowbit + '0';
  120.     count--;
  121.     if(!(nbr /= 5)) break;
  122.     }
  123.   while(count--) *str-- = ' ';
  124.   }
  125.  
  126. /*
  127. ** itoo -- convert nbr to unsigned octal string of width 7
  128. **         (including null) right adjusted, blank filled
  129. */
  130. static itoo(nbr, str) int nbr; char str[]; {
  131.   int count;
  132.   str = str+6; /* find end of string */
  133.   *str-- = 0; /* store ending null */
  134.   count = 6; /* remaining characters */
  135.   while(1) {
  136.     *str-- = (nbr & 7) + '0';
  137.     count--;
  138.     if(!(nbr = ((nbr >> 3) &  8191))) break;
  139.     }
  140.   while(count--) *str-- = ' ';
  141.   }
  142.  
  143. /*
  144. ** itox -- convert nbr to unsigned hexadecimal string of width 7
  145. **         (including null) right adjusted, blank filled
  146. */
  147. static itox(nbr, str) int nbr; char str[]; {
  148.   int count, digit;
  149.   str = str+6; /* find end of string */
  150.   *str-- = 0; /* store ending null */
  151.   count = 6; /* remaining characters */
  152.   while(1) {
  153.     *str-- = ((digit = (nbr & 15)) < 10) ? (digit + '0') : (digit + ('A' - 10));
  154.     count--;
  155.     if(!(nbr = ((nbr >> 4) &  4095))) break;
  156.     }
  157.   while(count--) *str-- = ' ';
  158.   }
  159.